package com.woniuxy.lab.woniu_lab_boss.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.woniuxy.lab.woniu_lab_boss.common.Result;
import com.woniuxy.lab.woniu_lab_boss.controller.form.AddTeacherForm;
import com.woniuxy.lab.woniu_lab_boss.exception.AccountException;
import com.woniuxy.lab.woniu_lab_boss.exception.TeacherException;
import com.woniuxy.lab.woniu_lab_boss.exception.WebException;
import com.woniuxy.lab.woniu_lab_boss.exception.WebExceptionCode;
import com.woniuxy.lab.woniu_lab_boss.model.Account;
import com.woniuxy.lab.woniu_lab_boss.model.Order;
import com.woniuxy.lab.woniu_lab_boss.model.Teacher;
import com.woniuxy.lab.woniu_lab_boss.dao.TeacherDao;
import com.woniuxy.lab.woniu_lab_boss.service.AccountService;
import com.woniuxy.lab.woniu_lab_boss.service.TeacherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.lab.woniu_lab_boss.service.dto.OrderDto;
import com.woniuxy.lab.woniu_lab_boss.service.dto.TeacherDto;
import com.woniuxy.lab.woniu_lab_boss.util.JwtUtil;
import com.woniuxy.lab.woniu_lab_boss.util.WebUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static com.woniuxy.lab.woniu_lab_boss.exception.WebExceptionCode.*;

/**
 * <p>
 * 讲师表 服务实现类
 * </p>
 *
 * @author Silas
 * @since 2023-03-15
 */
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {

    public static final String TEACHER = "TEACHER";
    public static final String LAP_BOSS_TOKEN = "lap-boss-token";

    @Resource
    private TeacherDao teacherDao;
    @Resource
    private AccountService accountService;

    /**
     * 从token中获取teacherId
     *
     * @return teacherId
     */
    @Override
    public Integer getTeacherId() {
        String token = WebUtil.getRequest().getHeader(LAP_BOSS_TOKEN);
        if (ObjectUtil.isEmpty(token)) {
            throw new AccountException(NOT_LOGIN);
        }
        //从token中获取ID
        Integer accountId = JwtUtil.getUserIdFromReq();
        String userType = JwtUtil.getUserTypeFromReq();
        Integer teacherId = JwtUtil.getUserPersonFromReq();
        //非讲师账号
        if (!userType.equals(TEACHER)) {
            throw new TeacherException(TEACHER_STATUS_EXCEPTION);
        }
        Account account = accountService.getById(accountId);
        //账号不存在
        if (ObjectUtil.isEmpty(account)) {
            throw new AccountException(ACCOUNT_IS_NOT_EXISTS);
        }
        //数据有误
        if (!account.getPersonId().equals(teacherId)) {
            throw new TeacherException(DATA_ERROR);
        }
        return teacherId;
    }

    @Override
    public IPage<TeacherDto> search(String condition, Integer page, Integer size) {
        IPage<Teacher> iPage = new Page<>(page == null ? 1 : page, size == null ? 4 : size);
        IPage<Teacher> page1 = teacherDao.selectPage(iPage, new QueryWrapper<Teacher>().eq("username", condition));
        return page1.convert(u -> {
            TeacherDto teacherDto = new TeacherDto();
            BeanUtils.copyProperties(u, teacherDto);
            return teacherDto;
        });
    }

    @Override
    public IPage<TeacherDto> findAll(Integer page, Integer size) {
        IPage<Teacher> iPage = new Page<>(page == null ? 1 : page, size == null ? 4 : size);
        IPage<Teacher> page1 = teacherDao.selectPage(iPage, new QueryWrapper<Teacher>().orderByDesc("id"));
        return page1.convert(u -> {
            TeacherDto teacherDto = new TeacherDto();
            BeanUtils.copyProperties(u, teacherDto);
            return teacherDto;
        });
    }

    @Override
    public void addTeacher(String username, String password) {
        Account one = accountService.getOne(new QueryWrapper<Account>().eq("username", username));
        if (one != null) throw new WebException(WebExceptionCode.USERNAME_IS_EXISTS);
        Teacher tea = getOne(new QueryWrapper<Teacher>().eq("username", username));
        if (tea != null) throw new WebException(WebExceptionCode.USERNAME_IS_EXISTS);
        Teacher teacher = new Teacher();
        teacher.setUsername(username);
        teacher.setPassword(new BCryptPasswordEncoder().encode(password));
        teacher.setStatus("ENABLE");
        save(teacher);
        Account account = new Account();
        account.setUsername(username);
        account.setPassword(new BCryptPasswordEncoder().encode(password));
        account.setType("TEACHER");
        Teacher teac = getOne(new QueryWrapper<Teacher>().eq("username", teacher.getUsername()));
        account.setPersonId(teac.getId());
        accountService.save(account);
    }

    @Override
    public void modifyTeacher(Integer teacherId) {
        Teacher teacher = getById(teacherId);
        if (teacher == null) throw new WebException(WebExceptionCode.TEACHER_IS_NOT_EXISTS);
        if ("ENABLE".equals(teacher.getStatus())) {
            teacher.setStatus("DISABLE");
            updateById(teacher);
        } else if ("DISABLE".equals(teacher.getStatus())) {
            teacher.setStatus("ENABLE");
            updateById(teacher);
        } else {
            throw new WebException(WebExceptionCode.STATUS_IS_WRONG);
        }
    }

    @Override
    public void changePassword(Integer teacherId, String password, String newPass) {
        if (password.equals(newPass)) throw new WebException(NEWPASSWORD_IS_ALREADY_OLDPASSWORD);
        Teacher teacher = getById(teacherId);
        if (teacher == null) throw new WebException(WebExceptionCode.TEACHER_IS_NOT_EXISTS);
        if (!new BCryptPasswordEncoder().matches(password, teacher.getPassword()))
            throw new WebException(WebExceptionCode.PASSWORD_IS_WRONG);
        teacher.setPassword(new BCryptPasswordEncoder().encode(newPass));
        updateById(teacher);
        Account account = accountService.getOne(new QueryWrapper<Account>().eq("type", "TEACHER").eq("person_id", teacherId));
        account.setPassword(new BCryptPasswordEncoder().encode(newPass));
        accountService.updateById(account);
    }

    @Override
    public void resetPassword(Integer teacherId) {
        Teacher teacher = getById(teacherId);
        if (teacher == null) throw new WebException(TEACHER_IS_NOT_EXISTS);
        teacher.setPassword(new BCryptPasswordEncoder().encode("111"));
        updateById(teacher);
        Account account = accountService.getOne(new QueryWrapper<Account>().eq("type", "TEACHER").eq("person_id", teacherId));
        account.setPassword(new BCryptPasswordEncoder().encode("111"));
        accountService.updateById(account);
    }
}
